package com.zkingsoft.zkingbase.widget;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import android.widget.ImageView;

import com.zkingsoft.zkingbase.R;

/**
 * Created by ytf on 2016/10/19.
 */

public class CircleImageView extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener
{

    private float borderWidthRatio = 0.05f;
    private Paint mBorderPaint;
    private Paint mBmpPaint;
    private Paint mShadowPaint;
    private float radius;
    private float borderWidth;
    private float shadowWidth;
    private Bitmap mSrcBmp;
    private float centerX;
    private float centerY;

    public CircleImageView(Context context)
    {
        super(context);
        init();
    }

    public CircleImageView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        init();
    }

    public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init()
    {
        setScaleType(ScaleType.CENTER);
        if (getDrawable() != null)
        {
            mSrcBmp = drawable2Bitmap(getDrawable());
        }
        mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setColor(Color.WHITE);
        mBmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mShadowPaint.setStyle(Paint.Style.FILL);
    }

    public void setBorderColor(int color)
    {
        mBorderPaint.setColor(color);
    }

    public static Bitmap drawable2Bitmap(Drawable drawable)
    {
        if (drawable instanceof BitmapDrawable)
        {//转换成Bitmap
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof NinePatchDrawable)
        {//.9图片转换成Bitmap
            Bitmap bitmap = Bitmap.createBitmap(
                    drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight(),
                    drawable.getOpacity() != PixelFormat.OPAQUE ?
                            Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        } else
        {
            return null;
        }
    }

    @Override
    public void setImageDrawable(Drawable drawable)
    {
        super.setImageDrawable(drawable);
        mSrcBmp = drawable2Bitmap(drawable);
        isLayout = false;
    }

    @Override
    public void setImageBitmap(Bitmap bm)
    {
        super.setImageBitmap(bm);
        mSrcBmp = bm;
        isLayout = false;
    }

    @Override
    public void setImageResource(int resId)
    {
        super.setImageResource(resId);
        mSrcBmp = BitmapFactory.decodeResource(getContext().getResources(), resId);
        isLayout = false;
    }

    private int width;
    private int height;

    @Override
    protected void onAttachedToWindow()
    {
        super.onAttachedToWindow();
        getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    protected void onDetachedFromWindow()
    {
        getViewTreeObserver().removeGlobalOnLayoutListener(this);
        super.onDetachedFromWindow();
    }

    private boolean isLayout;

    @Override
    public void onGlobalLayout()
    {
        if (!isLayout & mSrcBmp != null)
        {
            isLayout = true;

            width = getWidth();
            height = getHeight();

            int i = Math.min(width, height);
            width = height = i;
            centerX = width / 2.0f;
            centerY = height / 2.0f;
            float temp = width / 2;
            borderWidth = temp * borderWidthRatio;
            shadowWidth = borderWidth;
            if (allowDrawingStroke)
            {
                if (allowDrawingShadow)
                {
                    radius = temp - borderWidth - shadowWidth;
                } else
                {
                    radius = temp - borderWidth;
                }
            } else
            {
                radius = temp;
            }
            Matrix matrix = new Matrix();
            int refDimen = Math.min(mSrcBmp.getWidth(), mSrcBmp.getHeight());
            float rate = radius * 2.0f / refDimen;
            if (rate != 1)
            {
                matrix.setScale(rate, rate);
                mSrcBmp = Bitmap.createBitmap(mSrcBmp, 0, 0, refDimen, refDimen, matrix, true);
            }

        }
    }

//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
//    {
//        int width = MeasureSpec.getSize(widthMeasureSpec);
//        int height = MeasureSpec.getSize(heightMeasureSpec);
//        int wmode = MeasureSpec.getMode(widthMeasureSpec);
//        int hmode = MeasureSpec.getMode(heightMeasureSpec);
//        int refW =0, refH=0;
//        if(mSrcBmp != null)
//        {
//            refW = mSrcBmp.getWidth();
//            refH = mSrcBmp.getHeight();
//            refW = refH = Math.min(refW, refH);
//        }
//        if(wmode == MeasureSpec.AT_MOST)
//        {
//            width = refW;
//        }
//        if(hmode == MeasureSpec.AT_MOST)
//        {
//            height = refH;
//        }
//        int d = Math.min(width, height);
//        super.setMeasuredDimension(d, d);
//    }

    private boolean allowDrawingStroke = true;

    /***
     * 是否允许绘制边框， 默认允许
     */
    public void disallowStrokeDrawing()
    {
        allowDrawingStroke = false;
    }

    private boolean allowDrawingShadow;

    /***
     * 是否允许绘制阴影，默认允许，必须在允许绘制边框的前提下才可以绘制阴影
     */
    public void allowShadowDrawing()
    {
        allowDrawingShadow = true;
    }

    @Override
    protected void onDraw(Canvas canvas)
    {

        if (allowDrawingShadow)
        {
            drawShadow(canvas);
            drawCircleImage(canvas);
            if (allowDrawingStroke)
            {
                drawShader(canvas);
            }
        } else
        {
            drawCircleImage(canvas);
            if (allowDrawingStroke)
            {
                drawShader(canvas);
            }
        }
    }

    private void drawShadow(Canvas canvas)
    {

        Resources r = getContext().getResources();
        RadialGradient rg = new RadialGradient(centerX, centerY, centerX,
                new int[]{r.getColor(R.color.transparent), r.getColor(R.color.HalfBlack), r.getColor(R.color.transparent)},
                new float[]{0f, (radius + borderWidth) / centerX, 1.0f}, Shader.TileMode.CLAMP);
        Matrix matrix = new Matrix();
        matrix.setTranslate(0f, 3.0f);
        rg.setLocalMatrix(matrix);
        mShadowPaint.setShader(rg);
        canvas.drawCircle(centerX, centerY, centerX, mShadowPaint);
    }

    private void drawShader(Canvas canvas)
    {
        mBorderPaint.setStrokeWidth(borderWidth);
        if (allowDrawingShadow)
        {
            canvas.drawCircle(centerX, centerY, centerX - shadowWidth - borderWidth / 2.0f, mBorderPaint);
        } else
        {
            canvas.drawCircle(centerX, centerY, centerX - borderWidth / 2.0f, mBorderPaint);
        }
    }

    private void drawCircleImage(Canvas canvas)
    {
        mBmpPaint.setShader(new BitmapShader(mSrcBmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
        canvas.drawCircle(centerX, centerY, radius, mBmpPaint);
    }
}
